﻿'/*
' * FAHWatch7  Copyright Marvin Westmaas ( mtm )
' *
' * This program is free software; you can redistribute it and/or
' * modify it under the terms of the GNU General Public License
' * as published by the Free Software Foundation; version 2
' * of the License. See the included file GPLv2.TXT.
' * 
' * This program is distributed in the hope that it will be useful,
' * but WITHOUT ANY WARRANTY; without even the implied warranty of
' * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' * GNU General Public License for more details.
' * 
' * You should have received a copy of the GNU General Public License
' * along with this program; if not, write to the Free Software
' * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
' */
'/*	
Imports System.IO
Imports System.Text
Imports FAHWatch7.MyEventArgs
Public Class clsLogwindow
    'Inherits FAHWatch7.MyEventArgs
    Implements IDisposable
    'Public events
    Public Event log_hidden(sender As Object, e As EventArgs)
    Public Event warning_cleared(sender As Object, e As ClearWarningEventArgs)
    Public Event warning_set(sender As Object, e As WarningEventArgs)

#Region "log file"
    Private mLogFile As String = String.Empty
    Public ReadOnly Property logfile As String
        Get
            Return mLogFile
        End Get
    End Property
#End Region

#Region "warning status - set by a logged error "
    Private _Warning As Boolean = False 'Set when an error has been logged
    Public ReadOnly Property ActiveWarning As Boolean
        Get
            Return _Warning
        End Get
    End Property
    Public Sub ClearWarning(sender As Object, e As ClearWarningEventArgs)
        _Warning = False
        RaiseEvent warning_cleared(Me, Nothing)
    End Sub
#End Region

#Region "log form"
    Private WithEvents _Form As New frmLogWindow
    Public Overloads Sub ShowDebugWindow(Optional ByVal theIcon As Icon = Nothing, Optional ByVal exitApp As Boolean = False)
        Try
            If Not IsNothing(theIcon) Then
                If Not ActiveWarning Then
                    _Form.Icon = theIcon
                Else
                    _Form.Icon = My.Resources.iWarning
                End If
            Else
                If Not ActiveWarning Then
                    _Form.Icon = My.Resources.iLog
                Else
                    _Form.Icon = My.Resources.iWarning
                End If
            End If
            _Form.ScrollToEnd()
            _Form.Show()
            _Form.Focus()
            _Form.ExitWhenClosed = exitApp
        Catch ex As Exception
            WriteError(ex.Message, Err)
        End Try
    End Sub
    Public Sub HideDebugWindow()
        _Form.Visible = False
        RaiseEvent log_hidden(Me, New EventArgs)
    End Sub
    Public ReadOnly Property IsWindowActive() As Boolean
        Get
            Return _Form.Visible
        End Get
    End Property
    Private bAllowClose As Boolean = False
    Public ReadOnly Property Form As frmLogWindow
        Get
            Return _Form
        End Get
    End Property
    Private Sub _Form_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles _Form.FormClosing
        Try
            If e.CloseReason = CloseReason.WindowsShutDown Or e.CloseReason = CloseReason.ApplicationExitCall Then
                _Warning = False
                bAllowClose = True
                WriteLog("Application being closed by " & e.CloseReason.ToString)
            End If
            If Not bAllowClose Then
                e.Cancel = True
                _Form.Hide()
                RaiseEvent log_hidden(Me, Nothing)
            Else
                WriteLog("****** Closing logging class ******")
            End If
        Catch ex As Exception
            WriteError(ex.Message, Err)
        End Try
    End Sub
    Private Sub _Form_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles _Form.Resize
        If _Form.WindowState = FormWindowState.Minimized Then
            _Form.Hide()
        End If
    End Sub
#End Region

#Region "logging"
    Delegate Sub Addoutput(ByVal [text] As String)
    Friend Function CreateLog(Optional ByVal filename As String = "", Optional ByVal showicon As Boolean = False) As clsLogwindow
        Try
            _Form.rtLog.Clear()
            _Form.rtLog.MaxLength = Int32.MaxValue
            _Form.Icon = My.Resources.iLog
            _Form.nIcon.Text = Application.ProductName & Environment.NewLine & Application.ProductVersion.ToString
            If filename = "" Then
                If mLogFile = "" Then
                    filename = Application.StartupPath & "\" & Application.ProductName & ".log"
                Else
                    filename = mLogFile
                End If
            Else
                filename = filename
            End If
            mLogFile = filename
            If My.Computer.FileSystem.FileExists(filename) Then
                ' Don't store history from parsing?
                If My.Computer.FileSystem.FileExists(filename & ".old") Then My.Computer.FileSystem.DeleteFile(filename & ".old")
                My.Computer.FileSystem.CopyFile(filename, filename & ".old", True)
                My.Computer.FileSystem.DeleteFile(filename, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.DeletePermanently, FileIO.UICancelOption.DoNothing)
            End If
            ' TODO remove after diagnostics
            WriteLog("****** " & Application.ProductName & " " & My.Application.Info.Version.ToString & " logging started ******")
            Return Me
        Catch ex As Exception
            WriteError(ex.Message, Err)
            Return Me
        End Try
    End Function
    Friend Sub WriteLog(ByVal Message As String, Optional severity As eSeverity = eSeverity.Informative)
        Try
            Select Case severity
                Case eSeverity.Critical
                    Message = "CRITICAL: " & Message
                Case eSeverity.Important
                    Message = "WARNING: " & Message
                Case eSeverity.Informative
                    Message = Message
                Case eSeverity.Debug
                    Message = "DEBUG: " & Message
            End Select
#If DEBUG Then
            Message = "[" & DateTime.Now.ToShortDateString & "] * " & DateTime.Now.ToLongTimeString & " - " & Message
            Console.WriteLine(Message)
#End If
            If Not DebugOutput And severity = eSeverity.Debug Then Exit Sub
            If _Form.rtLog.InvokeRequired Then
                Dim nInvoke As New Addoutput(AddressOf wInv)
                _Form.rtLog.Invoke(nInvoke, New Object() {[Message]})
            Else
                _Form.rtLog.Text &= ("[" & DateTime.Now.ToShortDateString & "] * " & DateTime.Now.ToLongTimeString & " - " & Message & Environment.NewLine)
                _Form.rtLog.SaveFile(mLogFile, RichTextBoxStreamType.PlainText)
                If _Form.Visible Then _Form.ScrollToEnd()
            End If
        Catch ex As Exception
            WriteError(ex.Message, Err)
        End Try
    End Sub
    Public Sub WriteError(ByVal message As String, ByVal errObject As ErrObject)
        Try
            Dim strB As New StringBuilder
            strB.AppendLine(message)
            errObject = CType(errObject, ErrObject)
            strB.AppendLine(vbTab & vbTab & " - Err.source: " & errObject.Source & " Line: " & errObject.Erl & " - Err.number : " & errObject.Number)
            strB.AppendLine(vbTab & vbTab & " - Err.description: " & errObject.Description)
            strB.AppendLine(vbTab & vbTab & " - stacktrace: " & errObject.GetException.StackTrace.ToString)
            If Not ActiveWarning Then My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Exclamation)
            WriteLog(strB.ToString)
        Catch ex As Exception
            Dim strB As New StringBuilder
            strB.AppendLine("-ERROR: " & message)
            strB.AppendLine(vbTab & vbTab & " - Err.source: " & errObject.Source & " Line: " & errObject.Erl & " - Err.number : " & errObject.Number)
            strB.AppendLine(vbTab & vbTab & " - Err.description: " & errObject.Description)
            strB.AppendLine(vbTab & vbTab & " - stacktrace: " & errObject.GetException.StackTrace.ToString)
            WriteLog(strB.ToString)
        Finally
            _Form.Icon = My.Resources.iWarning
            _Warning = True
            RaiseEvent warning_set(Me, Nothing)
        End Try
    End Sub
    Friend Sub wInv(ByVal message As String)
        Try
            _Form.rtLog.Text &= ("[" & DateTime.Now.ToShortDateString & "] * " & DateTime.Now.ToLongTimeString & " - " & message & Environment.NewLine)
            _Form.rtLog.SaveFile(mLogFile, RichTextBoxStreamType.PlainText)
            If Not _Form.Focused AndAlso Not _Form.Visible Then Exit Sub
            With _Form.rtLog
                .SelectionLength = 0
                .SelectionStart = .TextLength
                .ScrollToCaret()
            End With
        Catch ex As Exception
            WriteError(ex.Message, Err)
        End Try
    End Sub
#End Region

    Public Sub CloseLog()
        WriteLog("Closing logging class")
        Dispose()
    End Sub


#Region "IDisposable Support"
    Private disposedValue As Boolean ' To detect redundant calls

    ' IDisposable
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: dispose managed state (managed objects).
                _Form.Dispose()
            End If

            ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
            ' TODO: set large fields to null.
        End If
        Me.disposedValue = True
    End Sub

    ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
    'Protected Overrides Sub Finalize()
    '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub

    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

End Class
